package com.itmck.lock;

import java.util.Map;
import java.util.Set;

/**
 * @author Lin
 * @date 2021-08-06
 */
public interface IRedisClient {
    /**
     * 删除一个或多个KEY
     *
     * @param keys
     * @return 被删除KEY的个数
     */
    long del(String... keys) ;

    /**
     * 查找所有满足指定模式的key集合
     *
     * @param pattern KEY的模式串
     * @return
     */
    Set<String> keys(String pattern);
    /**
     * 判断一个key是否存在
     *
     * @param key
     * @return
     */
    boolean exists(String key);

    /**
     * 设置一个key，多少秒钟后超时
     *
     * @param key
     * @param secTTL
     * @return
     */
    boolean expire(String key, int secTTL);
    /**
     * 返回过期时间
     *
     * @param key
     * @return
     */
    long getExpire(String key);

    /******************************************************************
     *                        Strings相关指令
     *****************************************************************/

    /**
     * 往指定key对应的value里追加数据
     *
     * @param key   KEY
     * @param value 追加数据
     * @return 追加后，key对应value的长度。
     */
    long append(String key, String value) ;

    /**
     * 设置一对KV值，V为String
     *
     * @param key
     * @param value
     * @return 成功true，失败false
     */
    boolean set(String key, String value);
    /**
     * 设置一对KV值, V为Object
     *
     * @param key
     * @param value
     * @return 成功true，失败false
     */
    boolean set(String key, Object value);

    /**
     * 当K不存在时，设置一对KV值
     *
     * @param key
     * @param value
     * @return
     */
    boolean setnx(String key, String value);

    /**
     * 当K不存在时，设置一对KV值
     *
     * @param key
     * @param value
     * @return
     */
    boolean setnx(String key, Object value);

    /**
     * 使用一个原子操作实现 nx ex 操作，防止在 nx 时 redis 客户端挂掉，导致 key 无法释放
     *
     * @param key
     * @param value
     * @param secTTL
     * @return
     */
    boolean setNxExAtomic(String key, Object value, long secTTL);

    /**
     * 设置一对KV值,带超时秒数
     * (注: 需要2.6.13才支持)
     *
     * @param key
     * @param value
     * @param secTTL
     * @return 成功true，失败false
     */
    boolean set(String key, String value, long secTTL);

    /**
     * 设置一对KV值,带超时秒数
     * (注: 需要2.6.13才支持)
     *
     * @param key
     * @param value
     * @param secTTL
     * @return 成功true，失败false
     */
    boolean set(String key, Object value, long secTTL) ;
    /**
     * 根据指定的KEY，获取对应的VALUE，VALUE为String
     *
     * @param key
     * @return
     */
    String get(String key);

    /**
     * 根据指定的KEY，获取对应的VALUE, VALUE为Object
     *
     * @param key
     * @return
     */
    Object getObject(String key);

    /**
     * 获取指定KEY，对应VALUE的长度
     *
     * @param key
     * @return
     */
    long strlen(String key);

    /**
     * 按步长1，递增
     *
     * @param key
     * @return
     */
    long incr(String key) ;

    /**
     * 按指定步长，递增
     *
     * @param key
     * @param increment
     * @return
     */
    long incrby(String key, int increment) ;

    /**
     * 按步长-1,递减
     *
     * @param key
     * @return
     */
    long decr(String key);
    /**
     * 按指定步长，递减
     *
     * @param key
     * @param decrement
     * @return
     */
    long decrby(String key, int decrement);



    /******************************************************************
     *                        Hashs相关指令
     *****************************************************************/

    /**
     * 删除一个或多个hash field
     *
     * @param key
     * @param fields
     * @return
     */
    long hdel(String key, String... fields);

    /**
     * 按指定步长，递增某个field
     *
     * @param key
     * @param field
     * @return
     */
    long hincrby(String key, String field, long value) ;


    /**
     * 批量设置K-V
     *
     * @param key
     * @param map
     * @return
     */
    boolean hmset(String key, Map<String, String> map);
    /**
     * 批量获取K-V
     *
     * @param key
     * @param fields
     * @return
     */
    Map<String, String> hmget(String key, String... fields);

    /**
     * 获取hash中所有的value
     *
     * @param key
     * @return
     */
    Set<String> hvals(String key) ;

    /**
     * 判断hash中是否存在指定的field
     *
     * @param key
     * @param field
     * @return
     */
    boolean hexists(String key, String field) ;

    /**
     * 获取hash中field对应的value
     *
     * @param key
     * @param field
     * @return
     */
    String hget(String key, String field) ;

    /**
     * 获取hash中所有的key
     *
     * @param key
     * @return
     */
    Set<String> hkeys(String key);

    /**
     * 往hash里设置K-V
     *
     * @param key
     * @param field
     * @param value
     * @return 如果hash中不存在filed则返回1，否则返回0
     */
    long hset(String key, String field, String value) ;

    /**
     * 获取hash中所有的K-V，屏蔽此函数
     *
     * @param key
     * @return
     */
    @SuppressWarnings("unused")
    Map<String, String> hgetAll(String key);

    /**
     * 返回hash中K-V对数量
     *
     * @param key
     * @return
     */
    long hlen(String key);

    /**
     * 当field不存在时，设置field-value对
     *
     * @param key
     * @param field
     * @param value
     * @return
     */
    long hsetnx(String key, String field, String value);



    /******************************************************************
     *                        Lists相关指令
     *****************************************************************/

    /**
     * 返回指定队列的长度
     *
     * @param key 队列名
     * @return
     */
    long llen(String key);

    /**
     * 从队列左边弹出一个数据，如果队列为空，则返回null
     *
     * @return
     */
    String lpop(String key) ;

    /**
     * 从队列右边弹出一个数据，如果队列为空，则返回null
     *
     * @return
     */
    String rpop(String key);

    /**
     * 从队列左边弹出一个数据，如果队列为空，则阻塞secTTL秒
     *
     * @param secTTL 多少秒后超时，传0表示不超时
     * @param keys   队列名
     * @return
     */
    String[] blpop(long secTTL, String... keys);

    /**
     * 从队列右边弹出一个数据，如果队列为空，则阻塞secTTL秒
     *
     * @param secTTL 多少秒后超时，传0表示不超时
     * @param keys   队列名
     * @return
     */
    String[] brpop(long secTTL, String... keys);

    /**
     * 往队列左端追加数据
     *
     * @param key    队列名
     * @param values 数据
     * @return 返回追加数据后的队列长度
     */
    long lpush(String key, String... values);
    
    /**
     * 往队列右端追加数据
     *
     * @param key    队列名
     * @param values 数据
     * @return 返回追加数据后的队列长度
     */
    long rpush(String key, String... values);

    /**
     * 当队列已经存在时，往队列左端追加数据
     *
     * @param key
     * @param value
     * @return
     */
    long lpushx(String key, String value);

    /**
     * 当队列已经存在时，往队列右端追加数据
     *
     * @param key
     * @param value
     * @return
     */
    long rpushx(String key, String value);

    /**
     * 从队列中，获取指定开始与结束位置之间的所有数据。
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    String[] lrange(String key, int start, int end);

    /**
     * 获取队列中指定位置的元素
     *
     * @param key
     * @param index
     * @return
     */
    String lindex(String key, int index);

    /**
     * 往队列指定位置设置数据
     *
     * @param key
     * @param index
     * @param value
     * @return
     */
    boolean lset(String key, int index, String value);

    /******************************************************************
     *                          Sets相关指令
     *****************************************************************/

    /**
     * 向集合中添加一个元素
     *
     * @param key
     * @param member
     * @return
     */
    long sadd(String key, String... member);

    /**
     * 获取集合中所有元素
     *
     * @param key
     * @return
     */
    Set<String> smembers(String key);


    /**
     * 从集合中删除一个元素
     *
     * @param key
     * @param member
     * @return
     */
    long srem(String key, String member);

    /**
     * 随机从集合中弹出一个元素
     *
     * @param key
     * @return
     */
    String spop(String key) ;

    /**
     * 将元素从一个集合移动到另一个集合
     *
     * @param srckey
     * @param dstkey
     * @param member
     * @return
     */
    long smove(String srckey, String dstkey, String member);

    /**
     * 获取集合中元素个数
     *
     * @param key
     * @return
     */
    long scard(String key) ;

    /**
     * 判断元素是否存在于集合中
     *
     * @param key
     * @param member
     * @return
     */
    boolean sismember(String key, String member);

    /**
     * 计算两个集合的交集
     *
     * @param keys
     * @return
     */
    Set<String> sinter(String[] keys);

    /**
     * 计算两个集合的交集，并存进另一个集合中
     *
     * @param dstkey
     * @param keys
     * @return
     */
    long sinterstore(String dstkey, String[] keys);

    /**
     * 计算两个集合的并集
     *
     * @param keys
     * @return
     */
    Set<String> sunion(String[] keys);

    /**
     * 计算两个集合的并集，并存进另一个集合中
     *
     * @param dstkey
     * @param keys
     * @return
     */
    long sunionstore(String dstkey, String[] keys);

    /**
     * 计算两个集合的差集
     *
     * @param keys
     * @return
     */
    Set<String> sdiff(String[] keys);

    /**
     * 计算两个集合的差集，并存储进另一个集合
     *
     * @param dstkey
     * @param keys
     * @return
     */
    long sdiffstore(String dstkey, String[] keys);
    
    /**
     * 随机获取集合中的一个元素
     *
     * @param key
     * @return
     */
    String srandmember(String key);
}
